module tb_top();
   
   logic [31:0] result;
   logic [15:0] a, b;
   logic 		sign;
   logic 		mode8;
   
   multiply_16x16_8x8 U_multiply(
								 .o_product(result),
								 .i_a(a),
								 .i_b(b),
								 .i_sign(sign),
								 .i_mode8(mode8)
								 );
   

   initial
     begin
   		#10;
		
		$display("=============== test 16x16 signed mode ===============");
		sign = 1'b1;
		mode8 = 1'b0;
		begin
		   int correct_result;
		   int r;
		   
		   for(int i=0;i<10000;i++)
			 begin
				r = $random;
				a = r[31:16];
				b = r[15:0];
				correct_result = $signed(a) * $signed(b);
				#1;				// FIXME:  wait the result ???
				if(result !== correct_result)
				  begin
					 $display("%d * %d = %d (%x)  <===>  %d (%x)   =>   %s", 
							  $signed(a), $signed(b), correct_result, correct_result,
							  $signed(result), result, ((result==correct_result) ? "Equal" : "!!! Not Equal !!!"));
					 $finish;
				  end
			 end // for (int i=0;i<10000;i++)
		   $display("passed");
		end
		
		
		$display("=============== test 16x16 unsigned mode ===============");
		sign = 1'b0;
		mode8 = 1'b0;
		begin
		   int unsigned correct_result;
		   int r;
		   for(int i=0;i<10000;i++)
			 begin
				r = $random;
				a = r[31:16];
				b = r[15:0];
				correct_result = a * b;
				#1;
				if(result !== correct_result)
				  begin
					 $display("%d * %d = %d (%x)  <===>  %d (%x)   =>   %s", 
							  a, b, correct_result, correct_result,
							  result, result, ((result==correct_result) ? "Equal" : "!!! Not Equal !!!"));
					 $finish;
				  end
			 end
		   $display("passed");
		end
		

		$display("=============== test 8x8 signed mode ===============");
		sign = 1'b1;
		mode8 = 1'b1;
		begin
		   shortint correct_result_L, correct_result_H;
		   int correct_result;
		   int r;
		   for(int i=0;i<10000;i++)
			 begin
				r = $random;
				a = r[31:16];
				b = r[15:0];
				correct_result_L = $signed(a[7:0]) * $signed(b[7:0]);
				correct_result_H = $signed(a[15:8]) * $signed(b[15:8]);
				correct_result = {correct_result_H, correct_result_L};
				#1;
				if(result !== correct_result)
				  begin
					 $display("%d*%d=%x,%d*%d=%x -> %x <===> %x  =>   %s", 
							  $signed(a[7:0]), $signed(b[7:0]), correct_result_L,
							  $signed(a[15:8]), $signed(b[15:8]), correct_result_H,
							  correct_result, result,
							  ((result==correct_result) ? "Equal" : "!!! Not Equal !!!"));
					 $finish;
				  end
			 end
		   $display("passed");
		end

					 
		$display("=============== test 8x8 unsigned mode ===============");
		sign = 1'b0;
		mode8 = 1'b1;
		begin
		   shortint unsigned correct_result_L, correct_result_H;
		   int 		unsigned correct_result;
		   int 		r;
		   for(int i=0;i<10000;i++)
			 begin
				r = $random;
				a = r[31:16];
				b = r[15:0];
				correct_result_L = a[7:0] * b[7:0];
				correct_result_H = a[15:8] * b[15:8];
				correct_result = {correct_result_H, correct_result_L};
				#1;
				if(result !== correct_result)
				  begin
					 $display("%d*%d=%x,%d*%d=%x -> %x <===> %x  =>   %s", 
							  a[7:0], b[7:0], correct_result_L,
							  a[15:8], b[15:8], correct_result_H,
							  correct_result, result,
							  ((result==correct_result) ? "Equal" : "!!! Not Equal !!!"));
					 $finish;
				  end
			 end
		   $display("passed");
		end

		// int unsigned n;
		// n = 32'd0;
		// while(1)
		//   begin
		// 	 // ...
		// 	 n += 1;
		// 	 if(n == 32'd0)
		// 	   break;
		//   end

     end
endmodule // tb_top
